/** 自定义文件上传 
 * @description: 自定义伦询
 * @param fetchFn: () => Promise<number> 请求函数
 * @param options: PollingOptions 配置项
 * interval: 轮询间隔时间
 * retryCount: 重试次数
 * immediate: 是否立即执行
 * onError: 错误回调
 * @Date: 2025-05-20
 * @Author: cy
*/

import { ref, computed, onUnmounted, type Ref } from "vue";

interface PollingOptions {
  interval?: number; 
  retryCount?: number; 
  immediate?: boolean; 
  onError?: (error: Error) => void;
  onDeltaChange?: (delta: number | null) => void; // 差值变化回调
  key?: Record<string, any>; // 数据列表的key
  backFun?: (data: any, key: Record<string, any>) => void; // 回调函数
}

export function usePollingWithDelta(
  fetchFn: () => Promise<number>, // 必须返回数字类型的请求函数
  options: PollingOptions = {}
): {
  count: Ref<number | null>; // 当前消息数量
  delta: Ref<number | null>; // 最新差值（当前 - 上次）
  previous: Ref<number | null>; // 上次消息数量
  error: Ref<Error | null>;
  start: () => void;
  stop: () => void;
  isPolling: Ref<boolean>;
  hasNewMessages: Ref<boolean>; // 是否有新增消息
} {
  const {
    interval = 3000,
    retryCount = 3,
    immediate = true,
    onError,
    onDeltaChange,
    backFun,
    key,
  } = options;

  const count = ref<number | null>(null);
  const previous = ref<number | null>(null);
  const error = ref<Error | null>(null);
  const isPolling = ref(false);
  let timer: ReturnType<typeof setInterval> | null = null;
  let currentRetry = 0;

  // 计算差值（响应式）
  const delta = computed(() => {
    if (count.value === null || previous.value === null) return null;
    return count.value - previous.value;
  });

  // 是否有新消息
  const hasNewMessages = computed(
    () => delta.value !== null && delta.value > 0
  );

  const execute = async () => {
    try {
      const newCount = await fetchFn();
      // 只有当值变化时更新（优化性能）
      if (newCount !== count.value) {
        previous.value = count.value;
        count.value = newCount;
        // 触发差值回调
        if (delta.value !== null && onDeltaChange) {
          onDeltaChange(delta.value);
        }
        if (backFun && typeof backFun === "function") {
          backFun(delta.value, key as Record<string, any>);
        }
      }

      error.value = null;
      currentRetry = 0;
    } catch (err) {
      error.value = err instanceof Error ? err : new Error(String(err));
      onError?.(error.value);

      if (currentRetry < retryCount) {
        currentRetry++;
        console.warn(`请求失败，第${currentRetry}次重试...`);
      } else {
        stop();
      }
    }
  };

  const start = () => {
    if (isPolling.value) return;
    isPolling.value = true;
    if (immediate) execute();
    timer = setInterval(execute, interval);
  };

  const stop = () => {
    timer && clearInterval(timer);
    timer = null;
    isPolling.value = false;
    currentRetry = 0;
  };

  onUnmounted(stop);

  return {
    count,
    delta,
    previous,
    error,
    start,
    stop,
    isPolling,
    hasNewMessages,
  };
}
